package org.ru.mse10.cvis.web.bean.action;

import java.io.IOException;
import java.io.OutputStream;

import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

import org.apache.myfaces.custom.fileupload.UploadedFile;
import org.ru.mse10.cvis.entity.cv.CvData;
import org.ru.mse10.cvis.entity.cv.EducationEntry;
import org.ru.mse10.cvis.entity.cv.KeyQualification;
import org.ru.mse10.cvis.entity.cv.LanguageSkill;
import org.ru.mse10.cvis.entity.cv.MembershipOfProfessionalBody;
import org.ru.mse10.cvis.entity.cv.OtherExpirience;
import org.ru.mse10.cvis.entity.cv.Position;
import org.ru.mse10.cvis.entity.cv.Skill;
import org.ru.mse10.cvis.entity.cv.YearsWithinACompany;
import org.ru.mse10.cvis.entity.fs.File;
import org.ru.mse10.cvis.service.CvService;
import org.ru.mse10.cvis.web.bean.BaseFormBean;
import org.ru.mse10.cvis.web.helper.ModelTableHelper;
import org.ru.mse10.cvis.web.model.initializer.DefaultInstanceInitializer;
import org.ru.mse10.cvis.web.model.initializer.EducationEntryInitializer;
import org.ru.mse10.cvis.web.model.initializer.OtherExpirienceInitializer;
import org.ru.mse10.cvis.web.model.initializer.YearsWithinCompanyInitializer;

/**
 * The Class CvAction.
 */
@SessionScoped
@ManagedBean(name = "cvAction")
public class CvAction extends BaseFormBean<CvData, CvService> {

	/** The service. */
	@EJB
	private CvService service;

	/** The cv. */
	private CvData cv;

	/** The current language. */
	private String currentLanguage;

	/** The preview. */
	private boolean preview;

	/** The fixed action div. */
	private boolean fixedActionDiv;

	/** The cv picture. */
	private UploadedFile cvPicture;

	/** The lang skill table helper. */
	private ModelTableHelper<LanguageSkill> langSkillTableHelper = new ModelTableHelper<LanguageSkill>(
			new DefaultInstanceInitializer<LanguageSkill>(LanguageSkill.class));

	/** The education table helper. */
	private ModelTableHelper<EducationEntry> educationTableHelper = new ModelTableHelper<EducationEntry>(
			new EducationEntryInitializer());

	/** The membership table helper. */
	private ModelTableHelper<MembershipOfProfessionalBody> membershipTableHelper = new ModelTableHelper<MembershipOfProfessionalBody>(
			new DefaultInstanceInitializer<MembershipOfProfessionalBody>(
					MembershipOfProfessionalBody.class));

	/** The others table helper. */
	private ModelTableHelper<OtherExpirience> othersTableHelper = new ModelTableHelper<OtherExpirience>(
			new OtherExpirienceInitializer());

	/** The years within company table helper. */
	private ModelTableHelper<YearsWithinACompany> yearsWithinCompanyTableHelper = new ModelTableHelper<YearsWithinACompany>(
			new YearsWithinCompanyInitializer());

	/** The key qualifications table helper. */
	private ModelTableHelper<KeyQualification> keyQualificationsTableHelper = new ModelTableHelper<KeyQualification>(
			new DefaultInstanceInitializer<KeyQualification>(
					KeyQualification.class));

	/** The other skills table helper. */
	private ModelTableHelper<Skill> otherSkillsTableHelper = new ModelTableHelper<Skill>(
			new DefaultInstanceInitializer<Skill>(Skill.class));

	/** The positions table helper. */
	private ModelTableHelper<Position> positionsTableHelper = new ModelTableHelper<Position>(
			new DefaultInstanceInitializer<Position>(Position.class));

	/**
	 * Inits the.
	 * 
	 * @param cv
	 *            the cv
	 * @return the string
	 */
	public String init(CvData cv) {
		if (cv.getId() != null) {
			service.find(CvData.class, cv.getId());
		}
		this.cv = cv;

		getLangSkillTableHelper().reset(getCv().getLanguageSkills());
		getEducationTableHelper().reset(getCv().getEducationEntries());
		getMembershipTableHelper().reset(
				getCv().getMembershipOfProfessionalBodies());
		getOthersTableHelper().reset(getCv().getOtherExpirience());
		getYearsWithinCompanyTableHelper().reset(
				getCv().getYearsWithinCompanies());
		getKeyQualificationsTableHelper().reset(getCv().getKeyQualifications());
		getOtherSkillsTableHelper().reset(getCv().getOtherSkills());
		getPositionsTableHelper().reset(getCv().getPositions());
		return "cvDetails";
	}

	/**
	 * Action create new.
	 * 
	 * @return the string
	 */
	public String actionCreateNew() {
		CvData cv = new CvData();
		cv.setLanguage("en");
		getLoggedUser().getCvs().put(cv.getLanguage(), cv);
		init(cv);
		setPreview(false);
		return "cvDetails";
	}

	/**
	 * Action edit cv.
	 */
	public void actionEditCv() {
		init(getCv());
		setPreview(false);
	}

	/**
	 * Action save cv.
	 */
	public void actionSaveCv() {
		if (cvPicture != null) {
			try {
				File file = new File();
				file.setData(cvPicture.getBytes());
				file.setMimeType(cvPicture.getContentType());
				file.setName(cvPicture.getName());
				cv.setCvPicture(file);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		getEducationTableHelper().pushTo(getCv().getEducationEntries());
		getLangSkillTableHelper().pushTo(getCv().getLanguageSkills());
		getMembershipTableHelper().pushTo(
				getCv().getMembershipOfProfessionalBodies());
		getOthersTableHelper().pushTo(getCv().getOtherExpirience());
		getYearsWithinCompanyTableHelper().pushTo(
				getCv().getYearsWithinCompanies());
		getKeyQualificationsTableHelper()
				.pushTo(getCv().getKeyQualifications());
		getOtherSkillsTableHelper().pushTo(getCv().getOtherSkills());
		getPositionsTableHelper().pushTo(getCv().getPositions());

		setCv(service.save(getCv()));
		init(getCv());
		setPreview(true);
	}

	/**
	 * Action cancel.
	 * 
	 * @return the string
	 */
	public String actionCancel() {
		if (cv.getId() != null) {
			service.refresh(cv);
			return init(cv);
		}
		return "home";
	}

	/**
	 * Paint.
	 * 
	 * @param os
	 *            the os
	 * @param data
	 *            the data
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	public void paint(OutputStream os, Object data) throws IOException {
		Long picId = (Long) data;
		File file = service.find(File.class, picId);
		os.write(file.getData());
	}

	/**
	 * Load for preview.
	 * 
	 * @param cvData
	 *            the cv data
	 * @return the string
	 */
	public String loadForPreview(CvData cvData) {
		setTargetEntity(cvData);
		init(cvData);
		setPreview(true);
		return "cvPreviewDetails";
	}

	/**
	 * Gets the cv.
	 * 
	 * @return the cv
	 */
	public CvData getCv() {
		return cv;
	}

	/**
	 * Sets the cv.
	 * 
	 * @param cv
	 *            the new cv
	 */
	public void setCv(CvData cv) {
		this.cv = cv;
	}

	/**
	 * Gets the current language.
	 * 
	 * @return the current language
	 */
	public String getCurrentLanguage() {
		return currentLanguage;
	}

	/**
	 * Sets the current language.
	 * 
	 * @param currentLanguage
	 *            the new current language
	 */
	public void setCurrentLanguage(String currentLanguage) {
		this.currentLanguage = currentLanguage;
	}

	/**
	 * Checks if is preview.
	 * 
	 * @return true, if is preview
	 */
	public boolean isPreview() {
		return preview;
	}

	/**
	 * Sets the preview.
	 * 
	 * @param preview
	 *            the new preview
	 */
	public void setPreview(boolean preview) {
		this.preview = preview;
	}

	/**
	 * Checks if is fixed action div.
	 * 
	 * @return true, if is fixed action div
	 */
	public boolean isFixedActionDiv() {
		return fixedActionDiv;
	}

	/**
	 * Sets the fixed action div.
	 * 
	 * @param fixedActionDiv
	 *            the new fixed action div
	 */
	public void setFixedActionDiv(boolean fixedActionDiv) {
		this.fixedActionDiv = fixedActionDiv;
	}

	/**
	 * Toggle fixed actions div.
	 */
	public void toggleFixedActionsDiv() {
		setFixedActionDiv(!isFixedActionDiv());
	}

	/**
	 * Gets the cv picture.
	 * 
	 * @return the cv picture
	 */
	public UploadedFile getCvPicture() {
		return cvPicture;
	}

	/**
	 * Sets the cv picture.
	 * 
	 * @param cvPicture
	 *            the new cv picture
	 */
	public void setCvPicture(UploadedFile cvPicture) {
		this.cvPicture = cvPicture;
	}

	/**
	 * Gets the lang skill table helper.
	 * 
	 * @return the lang skill table helper
	 */
	public ModelTableHelper<LanguageSkill> getLangSkillTableHelper() {
		return langSkillTableHelper;
	}

	/**
	 * Sets the lang skill table helper.
	 * 
	 * @param langSkillTableHelper
	 *            the new lang skill table helper
	 */
	public void setLangSkillTableHelper(
			ModelTableHelper<LanguageSkill> langSkillTableHelper) {
		this.langSkillTableHelper = langSkillTableHelper;
	}

	/**
	 * Gets the education table helper.
	 * 
	 * @return the education table helper
	 */
	public ModelTableHelper<EducationEntry> getEducationTableHelper() {
		return educationTableHelper;
	}

	/**
	 * Sets the education table helper.
	 * 
	 * @param educationTableHelper
	 *            the new education table helper
	 */
	public void setEducationTableHelper(
			ModelTableHelper<EducationEntry> educationTableHelper) {
		this.educationTableHelper = educationTableHelper;
	}

	/**
	 * Gets the membership table helper.
	 * 
	 * @return the membership table helper
	 */
	public ModelTableHelper<MembershipOfProfessionalBody> getMembershipTableHelper() {
		return membershipTableHelper;
	}

	/**
	 * Sets the membership table helper.
	 * 
	 * @param membershipTableHelper
	 *            the new membership table helper
	 */
	public void setMembershipTableHelper(
			ModelTableHelper<MembershipOfProfessionalBody> membershipTableHelper) {
		this.membershipTableHelper = membershipTableHelper;
	}

	/**
	 * Gets the others table helper.
	 * 
	 * @return the others table helper
	 */
	public ModelTableHelper<OtherExpirience> getOthersTableHelper() {
		return othersTableHelper;
	}

	/**
	 * Sets the others table helper.
	 * 
	 * @param othersTableHelper
	 *            the new others table helper
	 */
	public void setOthersTableHelper(
			ModelTableHelper<OtherExpirience> othersTableHelper) {
		this.othersTableHelper = othersTableHelper;
	}

	/**
	 * Gets the years within company table helper.
	 * 
	 * @return the years within company table helper
	 */
	public ModelTableHelper<YearsWithinACompany> getYearsWithinCompanyTableHelper() {
		return yearsWithinCompanyTableHelper;
	}

	/**
	 * Sets the years within company table helper.
	 * 
	 * @param yearsWithinCompanyTableHelper
	 *            the new years within company table helper
	 */
	public void setYearsWithinCompanyTableHelper(
			ModelTableHelper<YearsWithinACompany> yearsWithinCompanyTableHelper) {
		this.yearsWithinCompanyTableHelper = yearsWithinCompanyTableHelper;
	}

	/**
	 * Gets the key qualifications table helper.
	 * 
	 * @return the key qualifications table helper
	 */
	public ModelTableHelper<KeyQualification> getKeyQualificationsTableHelper() {
		return keyQualificationsTableHelper;
	}

	/**
	 * Sets the key qualifications table helper.
	 * 
	 * @param keyQualificationsTableHelper
	 *            the new key qualifications table helper
	 */
	public void setKeyQualificationsTableHelper(
			ModelTableHelper<KeyQualification> keyQualificationsTableHelper) {
		this.keyQualificationsTableHelper = keyQualificationsTableHelper;
	}

	/**
	 * Gets the other skills table helper.
	 * 
	 * @return the other skills table helper
	 */
	public ModelTableHelper<Skill> getOtherSkillsTableHelper() {
		return otherSkillsTableHelper;
	}

	/**
	 * Sets the other skills table helper.
	 * 
	 * @param otherSkillsTableHelper
	 *            the new other skills table helper
	 */
	public void setOtherSkillsTableHelper(
			ModelTableHelper<Skill> otherSkillsTableHelper) {
		this.otherSkillsTableHelper = otherSkillsTableHelper;
	}

	/**
	 * Gets the positions table helper.
	 * 
	 * @return the positions table helper
	 */
	public ModelTableHelper<Position> getPositionsTableHelper() {
		return positionsTableHelper;
	}

	/**
	 * Sets the positions table helper.
	 * 
	 * @param positionsTableHelper
	 *            the new positions table helper
	 */
	public void setPositionsTableHelper(
			ModelTableHelper<Position> positionsTableHelper) {
		this.positionsTableHelper = positionsTableHelper;
	}

}
